<?php

namespace Sharks\Core\Support\FrontEnd;

use Closure;
use Sharks\Core\AppContext;
use Sharks\Core\Support\Bag\ParameterBag;
use Sharks\Core\Support\Base\Precondition;
use Sharks\Core\Support\Log\Log;

/**
 * 静态资源引用。
 * 1. 通过在模板页面使用 {asset} 引用；2. 使用正确的资源处理；
 *
 * 生成的静态资源文件结构：
 * <pre>
 * return array(
 *     'name' => array(
 *         'type' => 'css', //文件类型，如css
 *         'url' => 'url', //可访问的url
 *     )
 * )
 * </pre>
 */
class Asset {

    private static $group;
    private static $assets;
    private static $assetHandler;

    /**
     * 静态资源group
     * @param  string   $name     group
     * @param  Closure  $callback 回调
     */
    public static function group($name, Closure $callback) {
        self::$group = $name;
        $callback();
        self::$group = null;
    }

    /**
     * 加入http资源
     * @param  string  $name 资源名称
     * @param  string  $url 资源url 
     */
    public static function http($name, $url) {
        Precondition::checkNotNull(self::$assets, 'Asset未正确初始化，$assets为NULL');

        if (!empty(self::$group)) {
            $name = self::$group . '.' . $name;
        }

        Precondition::check(!self::$assets->has($name), '已经存在名为%s的资源', $name);

        $extension = pathinfo(parse_url($url, PHP_URL_PATH), PATHINFO_EXTENSION);

        self::handle($name, $extension, $url);
    }

    /**
     * 获取资源的引用
     * @param string $name 资源名称
     */
    public static function get($name) {
        Precondition::checkNotNull(self::$assets, 'Asset未正确初始化，$assets为NULL');
        
        return self::$assets->get($name);
    }

    public static function put($name, $filePath, $moreAssetPath = null) {
    	Precondition::checkNotNull(self::$assets, 'Asset未正确初始化，$assets为NULL');

        if (!empty(self::$group)) {
            $name = self::$group . '.' . $name;
        }

    	Precondition::check(!self::$assets->has($name), '已经存在名为%s的资源', $name);

        if (!file_exists($filePath)) {
            Log::warning("$filePath 不存在");
            return;
        }

        
        $result = self::$assetHandler->line($filePath, $moreAssetPath);

        self::handle($name, $result->type, $result->url);
    }

    /**
     * 仅复制文件
     * @param  [type] $name 名称
     * @param  [type] $path [description]
     * @return [type]       [description]
     */
    public static function copy($name, $filePath, $moreAssetPath = null) {
        Precondition::checkNotNull(self::$assets, 'Asset未正确初始化，$assets为NULL');
        if (!file_exists($filePath)) {
            Log::warning("$filePath 不存在");
            return;
        }

        if (!empty(self::$group)) {
            $name = self::$group . '.' . $name;
        }

        $result = self::$assetHandler->copy($filePath, $moreAssetPath);

        self::handle($name, $result->type, $result->url);
    }

    public static function assemble($name, $callback) {
        $assetAssembler = new AssetAssembler();
        $callback($assetAssembler);

        self::$assets->put($name, array('type'=>'assemble', 'relateds'=>$assetAssembler->relateds(), 'outputs'=>$assetAssembler->outputs()));
    }



    /**
     * 静态资源初始化
     * @param  array  $assets [description]
     * @return [type]         [description]
     */
    public static function init(array $assets = array()) {
    	self::$assets = new ParameterBag($assets);
        self::$assetHandler = new AssetHandler;
    }

    public static function assets() {
    	if (is_null(self::$assets)) {
    		return null;
        }
        return self::$assets->all();
    }

    /**
     * 载入资源
     * @param $name
     * @return mixed
     */
    public static function load($name) {
        $set = self::$assets->get($name);
        if (null !== $set['type']) {
            switch ($set['type']) {
                case 'css':
                    return sprintf("<link rel='stylesheet' type='text/css' href='%s' />", $set['url']);
                    break;
                case 'js':
                    return sprintf("<script type='text/javascript' src='%s'></script>", $set['url']);
                    break;
                case 'jpg':
                case 'png':
                case 'jpeg':
                    return $set['url'];
                case 'assemble':
                    $assemble = array();
                    foreach ($set['relateds'] as $related) {
                        $assemble[] = self::load($related);
                    }

                    foreach ($set['outputs'] as $output) {
                        $assemble[] = $output;
                    }
                    return implode(PHP_EOL, $assemble);

                default:
                    return $set['url'];
            }
        }
        else {
            Log::warning("没有找到可处理的资源: $name");
            return sprintf("<!-- No Resource Named '%s' Find in Sharks' App Directory -->\n", $name);
        }
    }

    protected static function handle($name, $type, $url) {
        self::$assets->put($name, array('type'=>$type, 'url'=>$url));
    }
}
